<template>
  <div>
    <h1>连接蓝牙</h1>
    <p>count: {{ count }}</p>
    <p>当前连接成功的deviceId：{{ currentDeviceId }}</p>
    <button @click="add">count</button>
    <button @click="openBluetoothAdapter">开启蓝牙模块</button>
    <button @click="startBluetoothDevicesDiscovery">搜索蓝牙设备</button>
    <button @click="stopBluetoothDevicesDiscovery">停止搜索设备</button>
    <button @click="closeBluetoothAdapter">关闭蓝牙模块</button>
    <button @click="getServices">获取蓝牙服务</button>
    <button @click="getCharacteristics">获取特征值</button>
    <button @click="notify">开启消息监听</button>
    <button @click="send">发送数据</button>
    <view class="bluetooth-item" v-for="device in namedDevices" :key="device.deviceId">
      <view>
        deviceId: {{device.deviceId}}
      </view>
      <view>
        localName: {{ device.localName }}
      </view>
      <view>
        name: {{ device.name }}
      </view>
      <button size="mini" @click="connectDevice(device)">连接</button>
    </view>
  </div>
</template>
<script setup>
  import { computed, ref } from "vue"
  import { onLoad } from "@dcloudio/uni-app"
  const count = ref(100)
  
  const add = () => {
    count.value++
  }
  
  const openBluetoothAdapter = () => {
    uni.openBluetoothAdapter({
      success: (res) => {
        console.log('开启蓝牙成功');
        console.log(res);
      },
      fail: (res) => {
        console.log('开启蓝牙失败');
        console.log(res);
      }
    })
  }
  
  const deviceList = ref([])
  const namedDevices = computed(() => {
    return deviceList.value
    // return deviceList.value.filter(item => !!item.name || !!item.localName)
  })
  const startBluetoothDevicesDiscovery = () => {
    deviceList.value = []
    uni.startBluetoothDevicesDiscovery({
      success: (res) => {
        console.log('开启搜索蓝牙设备');
        console.log(res);
       
      },
      fail: (res) => {
        console.log('开启搜索蓝牙设备失败');
        console.log(res);
      }
    })
  }
  
  const stopBluetoothDevicesDiscovery = () => {
    uni.stopBluetoothDevicesDiscovery({
      success: (res) => {
        console.log('停止搜索设备,成功');
        console.log(res);
      },
      fail: (res) => {
        console.log('停止搜索失败');
        console.log(res);
      }
    })
  }
  
  onLoad(() => {
    uni.onBluetoothDeviceFound((res) => {
      console.log('监听寻找到新设备的事件');
      console.log(res);
       deviceList.value.push(res.devices[0])
    })
    
    uni.onBluetoothAdapterStateChange((res) => {
      console.log('监听蓝牙适配器状态变化事件');
      console.log(res);
    })
    
    uni.onBLEConnectionStateChange(function (res) {
      // 该方法回调中可以用于处理连接意外断开等异常情况
      console.log(`连接出现变化 device ${res.deviceId} state has changed, connected: ${res.connected}`)
    })
  })
  
  const closeBluetoothAdapter = () => {
    uni.closeBluetoothAdapter({
      success: (res) => {
        console.log('关闭蓝牙模块成功');
        console.log(res);
      },
      fail: (res) => {
        console.log('关闭蓝牙模块失败');
        console.log(res);
      },
      complete: () => {
        deviceList.value = []
      }
    })
  }
  
  // 当前连接成功的设备id
  const currentDeviceId = ref('')
  const connectDevice = (device) => {
    console.log('尝试连接', device);
    uni.stopBluetoothDevicesDiscovery({
      complete: () => {
        setTimeout(() => {
          uni.createBLEConnection({
            deviceId: device.deviceId,
            timeout: 10000,
            success: (res) => {
              console.log('连接成功')
              console.log(res);
              currentDeviceId.value = device.deviceId
            },
            fail: (res) => {
              console.log('连接失败');
              console.log(res);
              currentDeviceId.value = ''
              uni.closeBLEConnection({
                deviceId: device.deviceId
              })
            }
          })
        }, 1000)
      }
    })
    
  }
  
  const getServices = () => {
    uni.getBLEDeviceServices({
      deviceId: currentDeviceId.value, 
      success(res) {
        console.log('获取到设备的services');
          console.log(res)
      },
      fail(err) {
          console.error(err)
      }
    })
  }
  
  const characteristicId = ref('')
  function getCharacteristics() {
      uni.getBLEDeviceCharacteristics({
          deviceId: currentDeviceId.value,
          serviceId: '00001800-0000-1000-8000-00805F9B34FB', // 服务UUID
          success(res) {
              console.log('success', res)
              characteristicId.value = res.characteristics[0].uuid
          },
          fail(err) {
              console.error(err)
          }
      })
  }
  
  function notify() {
      uni.notifyBLECharacteristicValueChange({
          deviceId: currentDeviceId.value, 
          serviceId: '00001800-0000-1000-8000-00805F9B34FB',
          characteristicId: characteristicId.value, 
          success(res) {
              console.log('sucsss', res)
              
              // 接受消息的方法
              listenValueChange()
          },
          fail(err) {
              console.error('notify', err)
          }
      })
  }
  
  function listenValueChange() {
      uni.onBLECharacteristicValueChange(res => {
          // 结果
          console.log('onBLECharacteristicValueChange’', res)
      })
  }
  
  function send() {
      // 向蓝牙设备发送一个0x00的16进制数据
      
      let msg = 'hello'
      
      const buffer = new ArrayBuffer(msg.length)
      const dataView = new DataView(buffer)
      
      for (var i = 0; i < msg.length; i++) {
        dataView.setUint8(i, msg.charAt(i).charCodeAt())
      }
      
      uni.writeBLECharacteristicValue({
        deviceId: currentDeviceId.value, // 设备ID，
        serviceId: '00001800-0000-1000-8000-00805F9B34FB', // 服务UUID，
        characteristicId: characteristicId.value, // 特征值，
        value: buffer,
        success(res) {
          console.log('write success', res)
        },
        fail(err) {
          console.error(err)
        }
      })
  }
  
</script>
<style>
  .bluetooth-item {
    padding: 10rpx;
    border: 1rpx solid red;
  }
  
  .bluetooth-item + .bluetooth-item {
    margin-top: 10rpx;
  }
</style>